<template>
    <el-dialog v-model="modelValue" width="900px" draggable title="选择群聊" append-to-body @close="handleClose" top="8vh">
        <div class="search-group">
            <el-form :inline="true" :model="form" class="search-group-form">
                <el-form-item label="群名称">
                    <el-input v-model="form.title" clearable placeholder="请输入群名称" @keydown.enter="handleLocalSearch" />
                </el-form-item>
                <el-form-item label="群主">
                    <el-select v-model="form.ownerType" clearable placeholder="请选择群主">
                        <el-option v-for="item in OWNER_TYPE_LIST" :key="item.value" :label="item.label" :value="item.value" :disabled="isDisabled('ownerType', item.value)" />
                    </el-select>
                </el-form-item>
                <el-form-item label="群类型">
                    <el-select v-model="form.selectType" clearable placeholder="请选择群类型">
                        <el-option v-for="item in GROUP_TYPE_LIST" :key="item.value" :label="item.label" :value="item.value" :disabled="isDisabled('selectType', item.value)" />
                    </el-select>
                </el-form-item>
                <el-form-item label=" ">
                    <el-button type="primary" @click="handleLocalSearch" >查询</el-button>
                    <el-button @click="doClear" >清空</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div>
            <el-button type="primary" @click="handleSelectAll">选择全部数据</el-button>
        </div>
        <div class="checkbox-table" >
            <div class="search-select">
                <el-checkbox v-model="selectAllValue" :indeterminate="isIndeterminate" />
            </div>
            <el-checkbox-group v-model="checkSelectedData">
                <el-table v-loading="loading" ref="multipleTableRef" max-height="460px" row-key="id" :data="data" class="group-table" >
                    <el-table-column prop="selection" width="55">
                        <template #header>
                        </template>
                        <template #default="scope">
                            <el-checkbox :label="scope.row.id">
                                <span></span>
                            </el-checkbox>
                        </template>
                    </el-table-column>
                    <el-table-column label="群信息" show-overflow-tooltip min-width="120" >
                        <template #default="scope">
                            <div class="group_avatars">
                                <ZWGroupAvatar :avatars="scope.row.avatars" />
                            </div>
                            {{ scope.row.name ?? '-' }}
                        </template>
                    </el-table-column>
                    <el-table-column property="ownerName" show-overflow-tooltip label="群主" >
                        <template #default="scope">
                            {{ TABLE_OWNER_TYPE_MAP[scope.row.ownerType] ? `${TABLE_OWNER_TYPE_MAP[scope.row.ownerType]}(${scope.row.ownerName || '--'})` : scope.row.ownerName || '--' }} 
                        </template>
                    </el-table-column>
                    <el-table-column property="ownerType" label="群类型" min-width="60">
                        <template #default="scope">
                            {{ GROUP_TYPE_MAP[scope.row.groupType] || '--' }}
                        </template>
                    </el-table-column>
                    <el-table-column property="count" label="群人数" min-width="60" />
                    <el-table-column property="createDate" min-width="140" label="创建时间">
                        <template #default="scope">
                            {{ scope.row.createDate ?? '-' }}
                        </template>
                    </el-table-column>
                    <template #empty>
                        <el-empty />
                    </template>
                </el-table>
            </el-checkbox-group>
        </div>
        <ZWPagination ref="ZWPaginationRef" :total="total" @submit="handleSizeChange" />
        <template #footer>
            <span class="footer_count">已选择 {{ checkSelectedData.length ?? 0 }} 个群聊</span>
            <el-button @click="emit('update:modelValue', false)">取消</el-button>
            <el-button type="primary" @click="onSubmit">确定</el-button>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, onBeforeMount, nextTick, watchEffect } from 'vue'

import { getCustGroupchatList } from '@renderer/ajax/api/addGroupBuddy'
import ZWPagination from '@renderer/components/ZWPagination.vue'

import ZWGroupAvatar from './ZWGroupAvatar.vue'
import { GROUP_TYPE_MAP, GROUP_TYPE_LIST, OWNER_TYPE_LIST, TABLE_OWNER_TYPE_MAP, OWNER_TYPE_MAP } from './enum'

interface ISelectDisabled {
    /** 禁用的key */
    key: 'ownerType' | 'selectType'
    /** 禁用的值 */
    value: any,
    /** 默认禁用后选中的值，不要和value一样就行 */
    defaultSelected: any
}

interface Props {
    modelValue: boolean,
    selected: any[],
    httpRequest?: Function,
    selectDisabled?: ISelectDisabled[]
}
const props = withDefaults(defineProps<Props>(), {
    selectDisabled: () => []
})

const emit = defineEmits(['update:modelValue', 'submit', 'getTotal'])

const modelValue = computed({
    get() {
        return props.modelValue
    },
    set(val) {
        emit('update:modelValue', val)
    }
})

watch(modelValue, (val) => {
    if (val) {
        nextTick(() => {
            checkSelectedData.value = props.selected.map(x => x.id)
            ZWPaginationRef.value?.initPage()

            InitDisabledFormValue()
            handleLocalSearch()
        })
    }
})

/**
 * 弹窗关闭
 * @description 弹窗关闭时，重新清空筛选项并进行刷新
 */
const handleClose = () => {
    form.title = ''
    doSearch()
}

const form = reactive({
    // 0 所有 1 我 2 企业内 3 企业外
    ownerType: undefined,
    title: '',
    // 1 外部 2 内部
    selectType: undefined,
    page: 1,
    page_size: 15,
})
const total = ref(0)
/* ----------------------------选中项处理-start---------------------------- */
/** 选中的id */
const checkSelectedData = ref([])

// 当前页和全部页的多选
const selectAllValue = computed({
    get() {
        return data.some(selectItem => {
            return checkSelectedData.value.includes(selectItem.id)
        })
    },
    set(value) {
        // 设置为选中时
        if (value) {
            // 选中当前页的情况下,把目前页面的id存储进去
            checkSelectedData.value = [...new Set([...data.map(item => item.id), ...checkSelectedData.value])]
            return
        }

        // 取消勾选时
        // 选中当前页时，当前页的数据从数组中移除
        data.forEach(groupItem => {
            // 否则匹配到索引然后移除
            const removeIndex = checkSelectedData.value.indexOf(groupItem.id)
            // 如果当前项不再选中的，不做处理
            if (removeIndex === -1) {
                return
            }
            checkSelectedData.value.splice(removeIndex, 1)
        })
    }
})
// 当前页和全部页的多选的半选状态
const isIndeterminate = computed(() => {
    if (selectAllValue.value) {
        // 当前页的数据都存在的情况下
        return !data.every(item => checkSelectedData.value.includes(item.id))
    }
    return false
})

// 选择全部数据
const handleSelectAll = () => {
    // 未选择全部的情况下选择全部
    if (checkSelectedData.value?.length < searchTotalData.length) {
        // 全部页的数据
        checkSelectedData.value = searchTotalData.map(item => item.id)
    } else {
        // 否则移除全部页的数据
        checkSelectedData.value = []
    }
}
/* ----------------------------选中项处理-end---------------------------- */

/* ----------------------------默认禁用选择类型-start---------------------------- */
/** 禁用表单的存储值 */
const disabledForm = computed(() => {
    const disabledFormValue = {}
    props.selectDisabled.forEach(item => {
        if (disabledFormValue[item.key]) {
            disabledFormValue[item.key].value.push(item.value)
            return
        }
        disabledFormValue[item.key] = {
            value: [item.value],
            defaultSelected: item.defaultSelected
        }
    })
    return disabledFormValue
})

/**
 * 是否禁用当前的值
 * @param key 表单的key
 * @param value 某个选项的值
 */
const isDisabled = (key: 'ownerType' | 'selectType', value: any) => {
    if (disabledForm.value[key]) {
        return disabledForm.value[key].value.includes(value)
    }
    return false
}

/** 初始化禁用的默认值 */
const InitDisabledFormValue = () => {
    for (const key in form) {
        if (disabledForm.value[key]) {
            form[key] = disabledForm.value[key].defaultSelected
        }
    }
}

/** 如果不小心点了重置或者清空，则还原成禁用的默认值 */
watchEffect(() => {
    for (const key of ['ownerType', 'selectType']) {
        if (!form[key] || disabledForm.value[key]?.value?.includes(form[key])) {
            form[key] = disabledForm.value[key]?.defaultSelected
        }
    }

})
/* ----------------------------默认禁用选择类型-end---------------------------- */

/** 当前页的展示数据 */
const data = reactive([])
/** 搜索到的数据，数据源 */
const searchTotalData = reactive([])
const multipleTableRef = ref()
/** 所有数据，数据源 */
let totalData = []
const loading = ref(false)

// 清理表单筛选
const doClear = async () => {
    form.ownerType = undefined
    form.title = ''
    form.selectType = undefined
    // 这里是要等待watchEffact执行完之后
    await nextTick()
    handleLocalSearch()
}
const doSearch = async () => {
    try {
        loading.value = true
        // 默认先查询全部，然后再展示我的群聊
        const params = { ownerType: 0, title: '', selectType: 0 }
        const res = await (props.httpRequest ? props.httpRequest(params) : getCustGroupchatList(params))
        
        if (Array.isArray(res)) {
            totalData = res

            emit('getTotal', res.length)
            // 存储一下搜索的数据源。切换分页时需要用到
            searchTotalData.splice(0)
            searchTotalData.push(...res)

            total.value = totalData.length
            data.splice(0, data.length, ...totalData.slice(0, form.page_size))
        }
    } finally {
        loading.value = false
    }
}

/**
 * 本地查询做过滤
 * 不再做远程查询，使用本地查询，
 */
const handleLocalSearch = () => {
    const searchOption = [
        {
            key: 'title',
            searchFn: (groupItem) =>  groupItem.name.includes(form.title)
        },
        {
            key: 'ownerType',
            searchFn: (groupItem) =>  {
                if (form.ownerType === OWNER_TYPE_MAP['本企业全部成员']) {
                    return [
                        OWNER_TYPE_MAP['本企业全部成员'],
                        OWNER_TYPE_MAP['我']
                    ].includes(groupItem.ownerType)
                }
                return groupItem.ownerType === form.ownerType
            }
        },
        {
            key: 'selectType',
            searchFn: (groupItem) =>  groupItem.groupType === form.selectType
        }
    ]
    // 过滤当前选择的群聊类型。群主类型, 名称查询
    const searchData = totalData.filter(groupItem => {
        const searchOptionResult = searchOption.map(({ key, searchFn }) => {
            return form[key] ? searchFn(groupItem) : true
        })
        return searchOptionResult.every(flag => flag)
    })

    // 存储一下搜索的数据源。切换分页时需要用到
    searchTotalData.splice(0)
    searchTotalData.push(...searchData)

    // 设置搜索到的总数
    total.value = searchData.length
    ZWPaginationRef.value?.initPage()
    data.splice(0, data.length, ...searchData.slice(0, form.page_size))
}

const handleSizeChange = (page) => {
    Object.assign(form, page)
    const start = (page.page - 1) * page.page_size
    const sData = searchTotalData.slice(start, start + page.page_size)
    data.splice(0, data.length, ...sData)
}

const ZWPaginationRef = ref()
onBeforeMount(doSearch)

const onSubmit = () => {
    emit('update:modelValue', false)

    const selectedData = checkSelectedData.value.map(item => {
        return totalData.find(groupItem => groupItem.id === item) || props.selected.find(groupItem => groupItem.id === item)
    })
    emit('submit', {
        selectedData,
        selectType: form.selectType,
        // 选择全部页，选择全部，选择的数量和总是相同才是选择全部
        isAll: !form.ownerType && selectedData.length >= totalData.length
    })
}
defineExpose({
})
</script>
<style lang="scss" scoped>
.search-group {
    .search-group-form {
        display: flex;
        gap: 8px;
        justify-content: space-between;
        :deep(.el-form-item) {
            margin-right: auto;
        }
        :deep(.el-form-item__content) {
            width: 160px;
        }
    }
}

.footer_count {
    float: left;
}

.group_avatars {
    display: inline-block;
    width: 36px;
    height: 36px;
    vertical-align: middle;
    margin-right: 6px;
}
.checkbox-table {
    margin-top: 14px;
    position: relative;
    .search-select {
        position: absolute;
        top: 4px;
        left: 12px;
        z-index: 2;
    }
}
</style>
